home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UDeskScrapView.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  10.2 KB  |  369 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UDeskScrapView.cp
  3. // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UDESKSCRAPVIEW__
  7. #include "UDeskScrapView.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UCLIPBOARDMGR__
  13. #include "UClipboardMgr.h"
  14. #endif
  15.  
  16. #ifndef __UCOREUTILITIES__
  17. #include "UCoreUtilities.h"
  18. #endif
  19.  
  20. #ifndef __UDEBUG__
  21. #include "UDebug.h"
  22. #endif
  23.  
  24. #ifndef __UGEOMETRY__
  25. #include "UGeometry.h"
  26. #endif
  27.  
  28. #ifndef __UMACAPPGLOBALS__
  29. #include "UMacAppGlobals.h"
  30. #endif
  31.  
  32. #ifndef __UMACAPPUTILITIES__
  33. #include "UMacAppUtilities.h"
  34. #endif
  35.  
  36. #ifndef __UMEMORY__
  37. #include "UMemory.h"
  38. #endif
  39.  
  40. // Toolbox
  41.  
  42. #ifndef __ERRORS__
  43. #include <Errors.h>
  44. #endif
  45.  
  46. // ANSI
  47.  
  48. #ifndef __STDIO__
  49. #include <stdio.h>
  50. #endif
  51.  
  52.  
  53.  
  54. //========================================================================================
  55. // static data members
  56. //========================================================================================
  57. Boolean TDeskScrapView::gVarClipPicSize;
  58.  
  59. static Boolean LookForScrapType(ResType theResType, ResType& resTypeFound);
  60.  
  61. //========================================================================================
  62. // CLASS TDeskScrapView
  63. //========================================================================================
  64. #undef Inherited
  65. #define Inherited TView
  66.  
  67. #pragma segment MAInit
  68. MA_DEFINE_CLASS_M1(TDeskScrapView, Inherited);
  69.  
  70. //----------------------------------------------------------------------------------------
  71. // TDeskScrapView constructor
  72. //----------------------------------------------------------------------------------------
  73. #pragma segment MAInit
  74.  
  75. TDeskScrapView::TDeskScrapView()
  76. {
  77.     fDataHandle = NULL;
  78.     fHavePicture = FALSE;
  79.     fHaveText = FALSE;
  80.     fScrapCount = 0;
  81. } // TDeskScrapView::TDeskScrapView
  82.  
  83. //----------------------------------------------------------------------------------------
  84. // TDeskScrapView::IDeskScrapView: 
  85. //----------------------------------------------------------------------------------------
  86. #pragma segment MAInit
  87.  
  88. void TDeskScrapView::IDeskScrapView()
  89. {
  90.     VPoint itsSize(200, 200);
  91.     PScrapStuff aPtr;
  92.  
  93.     // Can't know the extent required until we actually read the data in, which we won't bother
  94.     // to do unless forced to by receiving an Update event
  95.  
  96.     this->IView(NULL, NULL, gZeroVPt, itsSize, sizeVariable, sizeVariable);
  97.  
  98.     aPtr = InfoScrap();
  99.     fScrapCount = aPtr->scrapCount - 1;
  100. } // TDeskScrapView::IDeskScrapView 
  101.  
  102. //----------------------------------------------------------------------------------------
  103. // TDeskScrapView destructor
  104. //----------------------------------------------------------------------------------------
  105. #pragma segment MAClipboard
  106.  
  107. TDeskScrapView::~TDeskScrapView()
  108. {
  109.     if (this == gClipboardMgr->fClipOrphanage)
  110.         gClipboardMgr->fClipOrphanage = NULL;
  111. }
  112.  
  113. //----------------------------------------------------------------------------------------
  114. // TDeskScrapView::Free: 
  115. //----------------------------------------------------------------------------------------
  116. #pragma segment MAClipboard
  117.  
  118. void TDeskScrapView::Free() // override
  119. {
  120.     // Never want to free gClipboardMgr->fClipOrphanage.
  121.     if (this != gClipboardMgr->fClipOrphanage)
  122.         Inherited::Free();
  123. } // TDeskScrapView::Free 
  124.  
  125. //----------------------------------------------------------------------------------------
  126. // TDeskScrapView::ReadFields: 
  127. //----------------------------------------------------------------------------------------
  128. #pragma segment MAInit
  129.  
  130. void TDeskScrapView::ReadFields(TStream* aStream)
  131. {
  132.     PScrapStuff aPtr;
  133.  
  134.     Inherited::ReadFields(aStream);
  135.  
  136.     aPtr = InfoScrap();
  137.     fScrapCount = (aPtr->scrapCount) - 1;
  138. } // TDeskScrapView::ReadFields 
  139.  
  140. //----------------------------------------------------------------------------------------
  141. // TDeskScrapView::CalcMinFrame: 
  142. //----------------------------------------------------------------------------------------
  143. #pragma segment MAClipboard
  144.  
  145. VRect TDeskScrapView::CalcMinFrame()// override 
  146. {
  147.     VRect minFrame(Inherited::CalcMinFrame());
  148.  
  149.     if (fDataHandle)
  150.         if (fHaveText)
  151.         {
  152.             // TEXT 
  153.             if (this->Focus())
  154.             {
  155.                 SetPortTextStyle(gSystemStyle);
  156.                 
  157.                 if (fSuperView)
  158.                 {
  159.                     minFrame = fSuperView->GetFrame();
  160.                     this->SuperToLocalVRect(minFrame);
  161.                 }
  162.                 CRect qdArea(ViewToQDRect(minFrame));
  163.                 
  164.                 if (GetHandleSize(fDataHandle) < 32000)    // more than 32000 characters will kill TECalText
  165.                 {
  166.                     TEHandle aTEHandle = TENew(qdArea, qdArea);
  167.                     FailNIL((Ptr)aTEHandle);
  168.     
  169.                     Handle oldHText = (*aTEHandle)->hText;    // We'll need this for TEDispose 
  170.                     (*aTEHandle)->hText = fDataHandle;
  171.     
  172.                     TECalText(aTEHandle);
  173.     
  174.                     minFrame.bottom = minFrame.top + Min((*aTEHandle)->nLines * (*aTEHandle)->lineHeight, kMaxCoord);
  175.     
  176.                     (*aTEHandle)->hText = oldHText;    // So TEDispose doesn't dispose our handle 
  177.     
  178.                     TEDispose(aTEHandle);
  179.                 }
  180.             }
  181.         }
  182.         else
  183.         {
  184. #if qDebugMsg
  185.             if (gIntenseDebugging)
  186.             {
  187.                 CRect picFrame = (**(PicHandle)fDataHandle).picFrame;
  188.                 fprintf(stderr, "Picture Frame:");
  189.                 fprintf(stderr, "%s\n", (const char *) picFrame);
  190.             }
  191. #endif
  192.             if (!gVarClipPicSize)
  193.             {
  194.                 CRect picFrame = (*((PicHandle)fDataHandle))->picFrame;
  195.                 minFrame[botRight] = minFrame[topLeft] + VPoint(picFrame.GetSize());
  196.             }
  197.         }
  198.  
  199.     return minFrame;
  200. } // TDeskScrapView::CalcMinFrame 
  201.  
  202. //----------------------------------------------------------------------------------------
  203. // TDeskScrapView::CheckScrapContents: 
  204. //----------------------------------------------------------------------------------------
  205. #pragma segment MAClipboard
  206.  
  207. void TDeskScrapView::CheckScrapContents()
  208. {
  209.     if (fScrapCount != gClipboardMgr->fNewScrapStuff.scrapCount)
  210.     {
  211.         // Make sure we get rid of the old scrap handle if necessary 
  212.         fDataHandle = DisposeIfHandle(fDataHandle);
  213.  
  214.         ResType resTypeFound;
  215.         fHavePicture = LookForScrapType('PICT', resTypeFound);
  216.         fHaveText = LookForScrapType('TEXT', resTypeFound);
  217.  
  218.         if (fHavePicture || fHaveText)
  219.         {
  220.             MAVolatileInit(Handle, aHandle, NULL);
  221.             aHandle = NewPermHandle(0);
  222.  
  223.             FailInfo fi;
  224.             Try(fi)
  225.             {
  226.                 Boolean savedPerm = PermAllocation(TRUE);
  227.                 long offset;
  228.                 long length = GetScrap(aHandle, resTypeFound, &offset);
  229.                 savedPerm = PermAllocation(savedPerm);
  230.  
  231.                 if (length < 0)                    // Only results < 0 are really errors 
  232.                     FailOSErr((OSErr)length);
  233.                 fDataHandle = aHandle;
  234.                 this->AdjustFrame();
  235.                 this->Focus();                    // Make sure we're still focused 
  236.                 fi.Success();
  237.             }
  238.             else    // Recover
  239.             {
  240.                 aHandle = DisposeIfHandle(aHandle);
  241.                 fDataHandle = NULL;
  242.                 fi.ReSignal();
  243.             }
  244.         }
  245.     }
  246. } // TDeskScrapView::CheckScrapContents 
  247.  
  248. //----------------------------------------------------------------------------------------
  249. // TDeskScrapView::Draw: 
  250. //----------------------------------------------------------------------------------------
  251. #pragma segment MAClipboard
  252.  
  253. void TDeskScrapView::Draw(const VRect& area)
  254. {
  255.     MAVolatile(SignedByte, savedState);
  256.     MAVolatileInit(Boolean, dataHandleIsLocked, FALSE);
  257.     
  258.     // Draw routine must not fail. Otherwise alert can cause an infinite loop of draw
  259.     // fail, alert, update event, draw fail, etc..
  260.     FailInfo fi;
  261.     Try(fi)
  262.     {
  263. #if qDebug
  264.         this->AssumeFocused();
  265. #endif
  266.  
  267.         // Has scrap been updated since we last drew? 
  268.         this->CheckScrapContents();
  269.     
  270.         CRect aRect;
  271.         if (fHaveText)
  272.         {
  273.             SetPortTextStyle(gApplicationStyle);
  274.             aRect = this->GetQDExtent();
  275.     
  276.             dataHandleIsLocked = TRUE;
  277.             savedState = LockHandle(fDataHandle);// Because MATextBox may move memory 
  278.             
  279.             MATextBox(*fDataHandle, GetHandleSize(fDataHandle), aRect, teFlushDefault, kAutoWrap, NULL, kNoEraseFirst, kNoSpaceForCaret);
  280.             
  281.             HSetState(fDataHandle, savedState);
  282.             dataHandleIsLocked = FALSE;
  283.         }
  284.         else if (fHavePicture)
  285.         {
  286.             if (gVarClipPicSize)
  287.                 aRect = this->GetQDExtent();
  288.             else
  289.                 aRect = CRect(gZeroPt, ((CRect &) (**((PicHandle)fDataHandle)).picFrame).GetSize());
  290.     
  291.             DrawPicture((PicHandle)fDataHandle, &aRect);
  292.         }
  293.     
  294.         if (fScrapCount != (gClipboardMgr->fNewScrapStuff.scrapCount))
  295.         {
  296.             this->ValidateRect(aRect);                // avoid flicker upon clipboard installation
  297.             fScrapCount = (gClipboardMgr->fNewScrapStuff.scrapCount);
  298.             gClipboardMgr->fClipWrittenToDeskScrap = TRUE;// Don't need to write it back out. 
  299.         }
  300.         fi.Success();
  301.     }
  302.     else // Recover
  303.     {
  304.         if (dataHandleIsLocked)
  305.         {
  306.             HSetState(fDataHandle, savedState);
  307.             dataHandleIsLocked = FALSE;
  308.         }
  309.         
  310.         // do nothing. We could draw a string "unable to show the clipboard at this time"
  311.         // definitely *don't* resignal.
  312.     }
  313.  
  314.     Inherited::Draw(area);
  315. } // TDeskScrapView::Draw 
  316.  
  317. //----------------------------------------------------------------------------------------
  318. // TDeskScrapView::SuperViewChangedFrame: 
  319. //----------------------------------------------------------------------------------------
  320. #pragma segment MAClipboard
  321.  
  322. void TDeskScrapView::SuperViewChangedFrame(const VRect& oldFrame,
  323.                                                  const VRect& newFrame,
  324.                                                  Boolean invalidate)// override 
  325. {
  326.     if (oldFrame.GetSize() != newFrame.GetSize())
  327.     {
  328.         this->AdjustFrame();
  329.         if (invalidate)
  330.         this->ForceRedraw();        // because of word wrap
  331.     }
  332. } // TDeskScrapView::SuperViewChangedFrame 
  333.  
  334. //----------------------------------------------------------------------------------------
  335. // TDeskScrapView::WriteToDeskScrap: 
  336. //----------------------------------------------------------------------------------------
  337. #pragma segment MAClipboard
  338.  
  339. void TDeskScrapView::WriteToDeskScrap()// override 
  340. {
  341.     // This view represents data that's already written to the desk scrap 
  342. } // TDeskScrapView::WriteToDeskScrap 
  343.  
  344. //----------------------------------------------------------------------------------------
  345. // LookForScrapType: 
  346. //----------------------------------------------------------------------------------------
  347. #pragma segment MAClipboard
  348.  
  349. Boolean TDeskScrapView::LookForScrapType(ResType theResType, ResType& resTypeFound)
  350. {
  351.     long offset;
  352.  
  353.     long dataLength = GetScrap(NULL, theResType, &offset);
  354.     if (dataLength > 0)
  355.         resTypeFound = theResType;
  356. #if qDebugMsg
  357.     if ((dataLength != noTypeErr) && (dataLength < 0))
  358.         fprintf(stderr, "LookForScrapType: err = %d\n", dataLength);
  359. #endif
  360.  
  361.     return (dataLength > 0);
  362. } // LookForScrapType 
  363.  
  364.  
  365. //----------------------------------------------------------------------------------------
  366. // End of UDeskScrapView.cp
  367.  
  368. #pragma segment Inline
  369.